//    Copyright (C) 2013  <lugocreation@gmail.com>
//
//    This program is free software: you can redistribute it and/or modify
//    it under the terms of the GNU General Public License as published by
//    the Free Software Foundation, either version 3 of the License, or
//    (at your option) any later version.
//
//    This program is distributed in the hope that it will be useful,
//    but WITHOUT ANY WARRANTY; without even the implied warranty of
//    MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
//    GNU General Public License for more details.
//
//    You should have received a copy of the GNU General Public License
//    along with this program.  If not, see <http://www.gnu.org/licenses/>.
package org.jpgolay.me.item;

import java.awt.event.*;
import java.math.BigDecimal;
import java.util.ArrayList;
import java.util.Iterator;
import javax.swing.*;
import org.jpgolay.gui.fixed.*;
import org.jpgolay.gui.iconBar.*;
import org.jpgolay.me.family.Family;
import org.jpgolay.me.persistence.ObjectCRUD;
import org.jpgolay.me.persistence.SQLList;
import org.jpgolay.me.supplier.Supplier;
import org.jpgolay.me.tax.Tax;
import org.jpgolay.me.util.*;

// Referenced classes of package org.jpgolay.me.item:
//            ItemGUI, ItemCRUD, ItemPrint, Item
public class ItemController extends ItemGUI {

    private class MouseClickList extends MouseAdapter {

        public void mouseClicked(MouseEvent e) {
            if (e.getClickCount() == 2) {
                actionLoad((String) itemTable.getTable().getValueAt(itemTable.getTable().getSelectedRow(), 0));
            }
        }

        MouseClickList() {
        }
    }

    public ItemController(Parameter param) {
        create = false;
        itemTable = null;
        write = false;
        this.param = param;
        crud = new ObjectCRUD();
        itemCrud = new ItemCRUD();
        date = new MEDate();
        initLaw();
        initMenu();
        initIconBar();
        initField();
        initComboBox();
        initSearch();
        initItemTable();
        initBatchTable();
    }

    private void initLaw() {
        if (param.getAccessLaw().length() >= 17 && param.getAccessLaw().charAt(17) == '1') {
            write = true;
        }
    }

    private void initMenu() {
        getMenuPanel().getExit().addActionListener(new ActionListener() {
            public void actionPerformed(ActionEvent evt) {
                actionExit();
            }
        });
        getMenuPanel().getDelete().addActionListener(new ActionListener() {
            public void actionPerformed(ActionEvent evt) {
                actionRemove();
            }
        });
        getMenuPanel().getHelp().addActionListener(new ActionListener() {
            public void actionPerformed(ActionEvent evt) {
                actionHelp();
            }
        });
        getMenuPanel().getModify().addActionListener(new ActionListener() {
            public void actionPerformed(ActionEvent evt) {
                actionModify();
            }
        });
        getMenuPanel().getNew().addActionListener(new ActionListener() {
            public void actionPerformed(ActionEvent evt) {
                actionNew();
            }
        });
        getMenuPanel().getOpen().addActionListener(new ActionListener() {
            public void actionPerformed(ActionEvent actionevent) {
            }
        });
        getMenuPanel().getPrint().addActionListener(new ActionListener() {
            public void actionPerformed(ActionEvent evt) {
                actionPrint(true);
            }
        });
        getMenuPanel().getSave().addActionListener(new ActionListener() {
            public void actionPerformed(ActionEvent evt) {
                actionSave();
            }
        });
    }

    private void initIconBar() {
        getIconBarPanel().addAnswerListener(new AnswerListener() {
            public void create(AnswerEvent e) {
                actionNew();
            }

            public void open(AnswerEvent answerevent) {
            }

            public void modify(AnswerEvent e) {
                actionModify();
            }

            public void save(AnswerEvent e) {
                actionSave();
            }

            public void remove(AnswerEvent e) {
                actionRemove();
            }

            public void print(AnswerEvent e) {
                actionPrint(false);
            }

            public void help(AnswerEvent e) {
                actionHelp();
            }
        });
    }

    private void initField() {
        cleanField();
        setEnabledField(false);
        getIconBarPanel().setEnabledCreate(write);
        getIconBarPanel().setEnabledSave(false);
        getIconBarPanel().setEnabledModify(false);
        getIconBarPanel().setEnabledRemove(false);
        getIconBarPanel().setEnabledPrint(false);
        getIconBarPanel().setEnabledOpen(false);
        getMenuPanel().getNew().setEnabled(write);
        getMenuPanel().getSave().setEnabled(false);
        getMenuPanel().getModify().setEnabled(false);
        getMenuPanel().getDelete().setEnabled(false);
        getMenuPanel().getPrint().setEnabled(false);
        getMenuPanel().getOpen().setEnabled(false);
        create = false;
        getBatchTable().setData(getBatchTableEmpty());
    }

    private void initComboBox() {
        setFamilyList(getItemFamilyList());
        setTaxList(getTaxList());
        setSupplierList(getSupplierList());
    }

    private String[] getItemFamilyList() {
        java.util.Collection c = crud.readAll(null, 12);
        if (c != null) {
            Family family = null;
            ArrayList familyList = new ArrayList(c);
            Iterator it = familyList.iterator();
            String list[] = new String[familyList.size()];
            for (int i = 0; it.hasNext(); i++) {
                family = (Family) it.next();
                list[i] = family.getId();
            }

            return list;
        } else {
            return (new String[]{
                        "aucune"
                    });
        }
    }

    private String[] getSupplierList() {
        java.util.Collection c = crud.readAll(null, 9);
        if (c != null) {
            Supplier supplier = null;
            ArrayList supplierList = new ArrayList(c);
            Iterator it = supplierList.iterator();
            String list[] = new String[supplierList.size()];
            for (int i = 0; it.hasNext(); i++) {
                supplier = (Supplier) it.next();
                list[i] = supplier.getId();
            }

            return list;
        } else {
            return (new String[]{
                        "aucune"
                    });
        }
    }

    private String[] getTaxList() {
        java.util.Collection c = crud.readAll(null, 18);
        if (c != null) {
            ArrayList arrayList = new ArrayList(c);
            Iterator it = arrayList.iterator();
            String s[] = new String[arrayList.size()];
            Tax tax = null;
            for (int i = 0; it.hasNext(); i++) {
                tax = (Tax) it.next();
                s[i] = tax.getTaux().setScale(2).toPlainString();
            }

            return s;
        } else {
            return (new String[]{
                        "aucune"
                    });
        }
    }

    private void initSearch() {
        getItemSearchBox().setList(new String[]{
                    "R\351f\351rence", "D\351signation", "Famille", "Fournisseur"
                });
        getItemSearchBox().setVal("");
        getItemSearchBox().setAdvanceSearch(getItemTable());
        getItemSearchBox().getButtonRight().addActionListener(new ActionListener() {
            public void actionPerformed(ActionEvent evt) {
                actionSearch();
            }
        });
        getItemSearchBox().getTextField().addActionListener(new ActionListener() {
            public void actionPerformed(ActionEvent evt) {
                actionSearch();
            }
        });
    }

    private void initItemTable() {
        itemTable.setTypes(new Class[]{
                    java.lang.String.class, java.lang.String.class, java.lang.String.class, java.lang.String.class
                });
        itemTable.setLastColumnNotEditable(0);
        itemTable.setCellEditable(false);
        itemTable.setAlternateColor(MEUtility.ITEM_LINE);
        itemTable.setColumnNames(new String[]{
                    "REFERENCE", "DESIGNATION", "FAMILLE", "FOURNISSEUR"
                });
        itemTable.setPreferredColumnSize(new int[]{
                    50, 50, 40, 40
                });
        actionSearch();
    }

    private TableViewer getItemTable() {
        if (itemTable == null) {
            itemTable = new TableViewer();
        }
        return itemTable;
    }

    private void initBatchTable() {
        getBatchTable().setTypes(new Class[]{
                    java.lang.String.class, java.lang.String.class, java.lang.String.class, java.math.BigDecimal.class, java.math.BigDecimal.class
                });
        getBatchTable().setLastColumnNotEditable(0);
        getBatchTable().setCellEditable(false);
        getBatchTable().setAlternateColor(MEUtility.BATCH_LINE);
        getBatchTable().setColumnNames(new String[]{
                    "N\260 Lot", "Code Frn", "Date", "Qt", "Pu"
                });
        getBatchTable().setPreferredColumnSize(new int[]{
                    60, 70, 80, 50, 50
                });
        getBatchTable().setData(getBatchTableEmpty());
    }

    private Object[][] getBatchTableEmpty() {
        Object data[][] = new Object[3][5];
        for (int i = 0; i < data.length; i++) {
            data[i][0] = null;
            if (i == 1) {
                data[i][1] = "AUCUN";
                data[i][2] = "LOT";
            } else {
                data[i][1] = null;
                data[i][2] = null;
            }
            data[i][3] = null;
            data[i][4] = null;
        }

        return data;
    }

    private void actionExit() {
        setVisible(false);
    }

    private void actionRemove() {
        int reponse = JOptionPane.showConfirmDialog(null, "Etes-vous certain de vouloir suprimer cet article ?", "Confirmation", 1, 2, null);
        switch (reponse) {
            case 0: // '\0'
                actionDelete();
            // fall through

            case -1:
            case 1: // '\001'
            case 2: // '\002'
            default:
                return;
        }
    }

    private void actionHelp() {
        BrowserControl.displayURL("www.media-4-u.net");
    }

    private void actionModify() {
        setEnabledField(true);
        getIconBarPanel().setEnabledCreate(false);
        getIconBarPanel().setEnabledSave(true);
        getIconBarPanel().setEnabledModify(false);
        getIconBarPanel().setEnabledRemove(true);
        getMenuPanel().getNew().setEnabled(false);
        getMenuPanel().getSave().setEnabled(true);
        getMenuPanel().getModify().setEnabled(false);
        getMenuPanel().getDelete().setEnabled(true);
    }

    private void actionNew() {
        initField();
        setEnabledField(true);
        getIconBarPanel().setEnabledCreate(false);
        getIconBarPanel().setEnabledSave(true);
        getMenuPanel().getNew().setEnabled(false);
        getMenuPanel().getSave().setEnabled(true);
        create = true;
    }

    private void actionPrint(boolean b) {
        ItemPrint prt = new ItemPrint(item, getBatchTable().getData(), b, param);
    }

    private void actionSave() {
        if (create) {
            actionCreate();
        } else {
            actionUpdate();
        }
    }

    private void actionSearch() {
        StringBuffer sql = new StringBuffer();
        sql.append("SELECT ref_code_barre, designation, familles_articles_id, fournisseurs_id FROM articles");
        switch (getItemSearchBox().getSelectedIndex()) {
            case 0: // '\0'
                if (getItemSearchBox().getVal().equals("")) {
                    sql.append(" ORDER BY ref_code_barre");
                } else {
                    sql.append(" WHERE ref_code_barre LIKE '");
                    sql.append(getItemSearchBox().getVal());
                    sql.append("%' ORDER BY ref_code_barre");
                }
                break;

            case 1: // '\001'
                if (getItemSearchBox().getVal().equals("")) {
                    sql.append(" ORDER BY designation");
                } else {
                    sql.append(" WHERE designation LIKE '");
                    sql.append(getItemSearchBox().getVal());
                    sql.append("%' ORDER BY designation");
                }
                break;

            case 2: // '\002'
                if (getItemSearchBox().getVal().equals("")) {
                    sql.append(" ORDER BY familles_articles_id");
                } else {
                    sql.append(" WHERE familles_articles_id LIKE '");
                    sql.append(getItemSearchBox().getVal());
                    sql.append("%' ORDER BY familles_articles_id");
                }
                break;

            case 3: // '\003'
                if (getItemSearchBox().getVal().equals("")) {
                    sql.append(" ORDER BY fournisseurs_id");
                } else {
                    sql.append(" WHERE fournisseurs_id LIKE '");
                    sql.append(getItemSearchBox().getVal());
                    sql.append("%' ORDER BY fournisseurs_id");
                }
                break;

            default:
                if (getItemSearchBox().getVal().equals("")) {
                    sql.append(" ORDER BY ref_code_barre");
                } else {
                    sql.append(" WHERE ref_code_barre LIKE '");
                    sql.append(getItemSearchBox().getVal());
                    sql.append("%' ORDER BY ref_code_barre");
                }
                break;
        }
        Object data[][] = itemCrud.getDataList(sql.toString());
        if (data != null) {
            itemTable.setData(data);
            itemTable.getTable().addMouseListener(new MouseClickList());
        } else {
            itemTable.setData(getEmptyTable());
        }
    }

    private Object[][] getEmptyTable() {
        Object data[][] = new Object[3][4];
        for (int i = 0; i < data.length; i++) {
            data[i][0] = null;
            if (i == 1) {
                data[i][1] = "AUCUN";
                data[i][2] = "ARTICLE";
            } else {
                data[i][1] = null;
                data[i][2] = null;
            }
            data[i][3] = null;
        }

        return data;
    }

    private void actionLoad(String pk) {
        item = (Item) crud.read(pk, 11);
        if (item != null) {
            initField();
            setImage1(item.getPhoto1());
            setImage10(item.getPhoto10());
            setImage2(item.getPhoto2());
            setImage3(item.getPhoto3());
            setImage4(item.getPhoto4());
            setImage5(item.getPhoto5());
            setImage6(item.getPhoto6());
            setImage7(item.getPhoto7());
            setImage8(item.getPhoto8());
            setImage9(item.getPhoto9());
            setId(item.getId());
            setGtin(item.getGtin());
            setDesignation(item.getDesignation());
            setDescription(item.getDescription());
            setFamily(item.getFamillesArticlesId());
            setWeb(item.getWeb());
            setSalesUnit(item.getUniteVente());
            setStockPlace(item.getEmplacement());
            setAlertStock(item.getAlerte().setScale(0).toString());
            setPackaging(item.getPackaging().toString());
            setBalancePrice(item.getPrixAchatPondere().setScale(param.getMinimumDecimalNumber().intValue(), param.getRoundType().intValue()).toString());
            setCostPrice(item.getPrixRevient().setScale(param.getMinimumDecimalNumber().intValue(), param.getRoundType().intValue()).toString());
            setCostPriceDetails(item.getDetailRevient());
            setPriceList1(item.getPriceList1().setScale(param.getMinimumDecimalNumber().intValue(), param.getRoundType().intValue()).toString());
            setPriceList2(item.getPriceList2().setScale(param.getMinimumDecimalNumber().intValue(), param.getRoundType().intValue()).toString());
            setPriceList3(item.getPriceList3().setScale(param.getMinimumDecimalNumber().intValue(), param.getRoundType().intValue()).toString());
            setPriceList4(item.getPriceList4().setScale(param.getMinimumDecimalNumber().intValue(), param.getRoundType().intValue()).toString());
            setPromotion(item.getPromotion().setScale(param.getMinimumDecimalNumber().intValue(), param.getRoundType().intValue()).toString());
            setTax(item.getTvaId().intValue() - 1);
            setSupplier(item.getFournisseurId());
            setDate(item.getDate());
            setNotes(item.getCommentaire());
            setUpdateTime(item.getUpdateLastTime());
            setUpdateUser(item.getUserId());
            setTitle("ARTICLE (CODE : " + item.getId() + ")");
            actionLoadBatch(item.getId());
            getIconBarPanel().setEnabledModify(write);
            getIconBarPanel().setEnabledPrint(true);
            getMenuPanel().getModify().setEnabled(write);
            getMenuPanel().getPrint().setEnabled(true);
        }
    }

    private void actionLoadBatch(String itemId) {
        if (sqlList == null) {
            sqlList = new SQLList();
        }
        if (sqlList.search("SELECT item_batch, supplier_id, input_stock_date, input_stock_quantity, ( batch_price/input_stock_quantity) FROM batch WHERE item_id='" + itemId + "'")) {
            Object data[][] = sqlList.getRowsData();
            BigDecimal balancePrice = new BigDecimal("0.00");
            for (int i = 0; i < data.length; i++) {
                data[i][2] = date.toME((String) data[i][2]);
                data[i][3] = (new BigDecimal((String) data[i][3])).setScale(param.getMinimumDecimalNumber().intValue(), param.getRoundType().intValue());
                data[i][4] = (new BigDecimal((String) data[i][4])).setScale(param.getMinimumDecimalNumber().intValue(), param.getRoundType().intValue());
                balancePrice = balancePrice.add((BigDecimal) data[i][4]);
            }

            balancePrice = balancePrice.divide(new BigDecimal(data.length), param.getMinimumDecimalNumber().intValue(), param.getRoundType().intValue());
            getBatchTable().setData(data);
            setBalancePrice(balancePrice.toPlainString());
        } else {
            getBatchTable().setData(getBatchTableEmpty());
        }
    }

    private void actionUpdate() {
        if (verifyRequirement()) {
            item.setPhoto1(getImage1());
            item.setPhoto10(getImage10());
            item.setPhoto2(getImage2());
            item.setPhoto3(getImage3());
            item.setPhoto4(getImage4());
            item.setPhoto5(getImage5());
            item.setPhoto6(getImage6());
            item.setPhoto7(getImage7());
            item.setPhoto8(getImage8());
            item.setPhoto9(getImage9());
            item.setGtin(getGtin());
            item.setDesignation(getDesignation());
            item.setDescription(getDescription());
            item.setFamillesArticlesId(getFamily());
            item.setWeb(getWeb());
            item.setUniteVente(getSalesUnit());
            item.setEmplacement(getStockPlace());
            item.setAlerte(new BigDecimal(getAlertStock()));
            item.setPackaging(new Integer(getPackaging()));
            item.setPrixAchatPondere(new BigDecimal(getBalancePrice()));
            item.setPrixRevient(new BigDecimal(getCostPrice()));
            item.setDetailRevient(getCostPriceDetails());
            item.setPriceList1(new BigDecimal(getPriceList1()));
            item.setPriceList2(new BigDecimal(getPriceList2()));
            item.setPriceList3(new BigDecimal(getPriceList3()));
            item.setPriceList4(new BigDecimal(getPriceList4()));
            item.setPromotion(new BigDecimal(getPromotion()));
            item.setTvaId(new Integer(getTax() + 1));
            item.setFournisseurId(getSupplier());
            item.setDate(getDate());
            item.setCommentaire(getNotes());
            item.setUserId(param.getUserId());
            crud.update(item, 11);
            initField();
        }
    }

    private void actionCreate() {
        if (verifyRequirement()) {
            String pk = (String) crud.create(11, getId());
            if (pk != null) {
                item = (Item) crud.read(pk, 11);
                item.setPhoto1(getImage1());
                item.setPhoto10(getImage10());
                item.setPhoto2(getImage2());
                item.setPhoto3(getImage3());
                item.setPhoto4(getImage4());
                item.setPhoto5(getImage5());
                item.setPhoto6(getImage6());
                item.setPhoto7(getImage7());
                item.setPhoto8(getImage8());
                item.setPhoto9(getImage9());
                item.setGtin(getGtin());
                item.setDesignation(getDesignation());
                item.setDescription(getDescription());
                item.setFamillesArticlesId(getFamily());
                item.setWeb(getWeb());
                item.setUniteVente(getSalesUnit());
                item.setEmplacement(getStockPlace());
                item.setAlerte(new BigDecimal(getAlertStock()));
                item.setPackaging(new Integer(getPackaging()));
                item.setPrixAchatPondere(new BigDecimal(getBalancePrice()));
                item.setPrixRevient(new BigDecimal(getCostPrice()));
                item.setDetailRevient(getCostPriceDetails());
                item.setPriceList1(new BigDecimal(getPriceList1()));
                item.setPriceList2(new BigDecimal(getPriceList2()));
                item.setPriceList3(new BigDecimal(getPriceList3()));
                item.setPriceList4(new BigDecimal(getPriceList4()));
                item.setPromotion(new BigDecimal(getPromotion()));
                item.setTvaId(new Integer(getTax() + 1));
                item.setFournisseurId(getSupplier());
                item.setDate(getDate());
                item.setCommentaire(getNotes());
                item.setUserId(param.getUserId());
                crud.update(item, 11);
                initField();
            } else {
                JOptionPane.showMessageDialog(null, "Code Article refus\351 !\n(v\351rif\351 si ce code n'est pas d\351j\340 utilis\351)");
            }
        }
    }

    private void actionDelete() {
        crud.delete(item.getId(), item.getUpdateLastTime(), 11);
        initField();
    }

    private boolean verifyRequirement() {
        if (getId().length() < 1) {
            JOptionPane.showMessageDialog(null, "Code obligatoire (maxi. 50 caract\350res) !");
            return false;
        }
        if (getId().length() > 50) {
            JOptionPane.showMessageDialog(null, "Code trop long (maxi. 50 caract\350res) !");
            return false;
        }
        if (getGtin() != null && getGtin().length() > 50) {
            JOptionPane.showMessageDialog(null, "GTIN trop long (maxi. 50 caract\350res) !");
            return false;
        }
        if (getDesignation() != null && getDesignation().length() > 50) {
            JOptionPane.showMessageDialog(null, "D\351signation trop longue (maxi. 50 caract\350res) !");
            return false;
        }
        if (getDescription() != null && getDescription().length() > 250) {
            JOptionPane.showMessageDialog(null, "Descriptionn trop longue (maxi. 250 caract\350res) !");
            return false;
        }
        if (getStockPlace() != null && getStockPlace().length() > 50) {
            JOptionPane.showMessageDialog(null, "Emplacement trop long (maxi. 50 caract\350res) !");
            return false;
        }
        if (getCostPriceDetails() != null && getCostPriceDetails().length() > 50) {
            JOptionPane.showMessageDialog(null, "D\351tail prix de revient trop long (maxi. 50 caract\350res) !");
            return false;
        }
        if (getNotes() != null && getNotes().length() > 250) {
            JOptionPane.showMessageDialog(null, "Commentaire trop long (maxi. 250 caract\350res) !");
            return false;
        }
        try {
            new Integer(getPackaging());
        } catch (NumberFormatException nfe) {
            setPackaging("1");
        }
        try {
            new BigDecimal(getAlertStock());
        } catch (NumberFormatException nfe) {
            setAlertStock("0");
        }
        try {
            new BigDecimal(getBalancePrice());
        } catch (NumberFormatException nfe) {
            setBalancePrice("0.00");
            JOptionPane.showMessageDialog(null, "Prix pond\350r\351 refus\351 (nombre d\351cimal uniquement) !");
        }
        try {
            new BigDecimal(getCostPrice());
        } catch (NumberFormatException nfe) {
            setCostPrice("0.00");
            JOptionPane.showMessageDialog(null, "Prix de revient refus\351 (nombre d\351cimal uniquement) !");
        }
        try {
            new BigDecimal(getPriceList1());
        } catch (NumberFormatException nfe) {
            setPriceList1("0.00");
            JOptionPane.showMessageDialog(null, "Prix de vente refus\351 (nombre d\351cimal uniquement) !");
        }
        try {
            new BigDecimal(getPriceList2());
        } catch (NumberFormatException nfe) {
            setPriceList2("0.00");
            JOptionPane.showMessageDialog(null, "Prix d'achat refus\351 (nombre d\351cimal uniquement) !");
        }
        try {
            new BigDecimal(getPriceList3());
        } catch (NumberFormatException nfe) {
            setPriceList3("0.00");
            JOptionPane.showMessageDialog(null, "Prix TG 1 (web) refus\351 (nombre d\351cimal uniquement) !");
        }
        try {
            new BigDecimal(getPriceList4());
        } catch (NumberFormatException nfe) {
            setPriceList4("0.00");
            JOptionPane.showMessageDialog(null, "Prix TG 2 (web) refus\351 (nombre d\351cimal uniquement) !");
        }
        try {
            new BigDecimal(getPromotion());
        } catch (NumberFormatException nfe) {
            setPromotion("0.00");
            JOptionPane.showMessageDialog(null, "Promotion refus\351e (nombre d\351cimal uniquement) !");
        }
        return true;
    }
    private ObjectCRUD crud;
    private ItemCRUD itemCrud;
    private SQLList sqlList;
    private Parameter param;
    private boolean create;
    private MEDate date;
    private Item item;
    private TableViewer itemTable;
    private boolean write;
}
